(function (window, undefined) {
    var doc = window.document;
    var docElement = doc.documentElement;
    var classPrefix = "yehun-dialog-";
    var dialogOverlayName = classPrefix + "overlay";
    var dialogBoxName = classPrefix + "box";
    var dialogCloseButtonName = classPrefix + "close-button";
    var dialogYesButtonName = classPrefix + "yes-button";
    var dialogNoButtonName = classPrefix + "no-button";

    var YehunDialog = function () {
        var body = doc.body;
        var uuid = 1;
        var expando = 'cache' + ( +new Date() + "" ).slice(-8);
        var cacheData = { };
        var Dialog = function () { };
        Dialog.prototype = {
            getOptions: function (args) {
                var options = {},
                    defaults = {
                        title: null,
                        content: null,
                        overlay: true,
                        yesCallback: null,
                        noCallback: null
                    };
                for (var i in defaults) {
                    options[i] = args[i] !== undefined ? args[i] : defaults[i];
                }
                Dialog.data('options', options);
                return options;
            },
            createOverlay: function () {
                var overlayNode = doc.createElement("div");
                overlayNode.style = "margin:0;padding:0;border:none;width:100%;height:100%;background:#333;opacity:0.6;filter:alpha(opacity=60);z-index:9999;position:fixed;top:0;left:0;";
                overlayNode.id = dialogOverlayName;
                return overlayNode;
            },
            createDialogBox: function () {
                var dialogBoxNode = doc.createElement("div");
                dialogBoxNode.style = "";
                dialogBoxNode.id = dialogBoxName;
                return dialogBoxNode;
            },
            createTamplate: function (args) {
                var headerNode = doc.createElement("div");
                var contentNode = doc.createElement("div");
                var yesButton = '';
                if (typeof args.yesCallback === "function") {
                    yesButton = doc.createElement("button");
                    yesButton.id = dialogYesButtonName;
                    yesButton.innerText = args.yesText === "string" ? args.yesText : "确定";
                }
                var noButton = '';
                if (typeof  args.noCallback === "function" || args.noCallback === true) {
                    noButton = doc.createElement("button");
                    noButton.id = dialogNoButtonName;
                    noButton.innerText = args.noText === "string" ? args.noText : "取消";
                }
                var footerNode = '';
                if (yesButton !== '' || noButton !== '') {
                    footerNode = doc.createElement("div");
                    if (yesButton !== '') {
                        footerNode.appendChild(yesButton);
                    }
                    if (noButton !== '') {
                        footerNode.appendChild(yesButton);
                    }
                }
                var templateArray = [headerNode, contentNode, footerNode];
                return templateArray.join('');
            }
        };
        /**
         * 设置并返回缓存的数据 关于缓存系统详见：http://stylechen.com/cachedata.html
         * @param elem  任意字符串或DOM元素
         * @param val   缓存属性名
         * @param data  缓存属性值
         * @return { Object } 返回该值
         */
        Dialog.data = function (elem, val, data) {
            if (typeof elem === 'string') {
                if (val !== undefined) {
                    cacheData[elem] = val;
                }
                return cacheData[elem];
            } else if (typeof elem === 'object') {
                // 如果是window、document将不添加自定义属性
                // window的索引是0 document索引为1
                var index = elem === window ? 0 : (elem.nodeType === 9 ? 1 : (elem[expando] ? elem[expando] : (elem[expando] = ++uuid)));
                var thisCache = cacheData[index] ? cacheData[index] : ( cacheData[index] = {} );
                if (data !== undefined) {
                    // 将数据存入缓存中
                    thisCache[val] = data;
                }
                // 返回DOM元素存储的数据
                return thisCache[val];
            }
        };

        Dialog.event = { //事件处理
            bind: function (elem, type, handler) {
                var events = Dialog.data(elem, 'e' + type) || Dialog.data(elem, 'e' + type, []);
                // 将事件函数添加到缓存中
                events.push(handler);
                // 同一事件类型只注册一次事件，防止重复注册
                if (events.length === 1) {
                    var eventHandler = this.eventHandler(elem);
                    Dialog.data(elem, type + 'Handler', eventHandler);
                    if (elem.addEventListener) {
                        elem.addEventListener(type, eventHandler, false);
                    }
                    else if (elem.attachEvent) {
                        elem.attachEvent('on' + type, eventHandler);
                    }
                }
            },
            unbind: function (elem, type, handler) {
                var events = Dialog.data(elem, 'e' + type);
                if (!events) return;

                // 如果没有传入要删除的事件处理函数则删除该事件类型的缓存
                if (!handler) {
                    events = undefined;
                }
                // 如果有具体的事件处理函数则只删除一个
                else {
                    for (var i = events.length - 1, fn = events[i]; i >= 0; i--) {
                        if (fn === handler) {
                            events.splice(i, 1);
                        }
                    }
                }
                // 删除事件和缓存
                if (!events || !events.length) {
                    var eventHandler = Dialog.data(elem, type + 'Handler');
                    if (elem.addEventListener) {
                        elem.removeEventListener(type, eventHandler, false);
                    }
                    else if (elem.attachEvent) {
                        elem.detachEvent('on' + type, eventHandler);
                    }
                    Dialog.removeData(elem, type + 'Handler');
                    Dialog.removeData(elem, 'e' + type);
                }
            },
            eventHandler: function (elem) { // 依次执行事件绑定的函数
                return function (event) {
                    event = Dialog.event.fixEvent(event || win.event);
                    var type = event.type,
                        events = Dialog.data(elem, 'e' + type);

                    for (var i = 0, handler; handler = events[i++];) {
                        if (handler.call(elem, event) === false) {
                            event.preventDefault();
                            event.stopPropagation();
                        }
                    }
                }
            },
            fixEvent: function (e) {
                // 支持DOM 2级标准事件的浏览器无需做修复
                if (e.target) return e;
                var event = {}, name;
                event.target = e.srcElement || document;
                event.preventDefault = function () {
                    e.returnValue = false;
                };
                event.stopPropagation = function () {
                    e.cancelBubble = true;
                };
                // IE6/7/8在原生的window.event中直接写入自定义属性
                // 会导致内存泄漏，所以采用复制的方式
                for (name in e) {
                    event[name] = e[name];
                }
                return event;
            }
        };

        var extend = {
            show: function () {
                var self = this;
                var event = Dialog.event;
                var _dialog = new Dialog();
                var options = _dialog.getOptions(arguments[0] || {});

                if (options.overlay) {
                    var overlay = doc.getElementById(dialogOverlayName);
                    if (!overlay) {
                        overlay = _dialog.createOverlay();
                        body.appendChild(overlay);
                    }
                    overlay.style.display = 'block';
                    event.bind(overlay, "click", self.close); //点击遮照事件
                }

                var dialogBox = doc.getElementById(dialogBoxName);
                if (!dialogBox) {
                    dialogBox = _dialog.createDialog();
                    body.appendChild(dialogBox);
                }

                var dialogCloseButton = doc.getElementById(dialogCloseButtonName),
                    dialogYesButton = doc.getElementById(dialogYesButtonName),
                    dialogNoButton = doc.getElementById(dialogNoButtonName);

                // 绑定确定按钮的回调函数
                if (dialogYesButton) {
                    event.bind(dialogYesButton, 'click', function (event) {
                        if (options.container.yesFn.call(self, event) !== false) {
                            self.close();
                        }
                    });
                }

                if (dialogNoButton) {
                    var noCallback = function (event) {
                        if (options.noCallback === true || options.noCallback.call(self, event) !== false) {
                            self.close();
                        }
                    };
                    event.bind(dialogNoButton, 'click', noCallback);
                    // 如果取消按钮有回调函数 关闭按钮也绑定同样的回调函数
                    if (dialogCloseButton) {
                        event.bind(dialogCloseButton, 'click', noCallback);
                    }
                } else if (dialogCloseButton) {
                    event.bind(dialogCloseButton, 'click', self.close);
                }
            },
            close: function () {
                var overlay = doc.getElementById(dialogOverlayName);
                if (overlay) {
                    overlay.style.display = 'none';
                }
            }
        };
        return extend;
    };

    var loaded = function () {
        window.yehunDialog = YehunDialog();
    };
    var doScrollCheck = function () {
        if (document.body) {
            return;
        }
        try {
            docElement.doScroll("left");
        } catch (e) {
            setTimeout(doScrollCheck, 1);
            return;
        }
        loaded();
    };

    (function () {
        if (doc.body) {
            loaded();
        } else {
            if (doc.addEventListener) {
                doc.addEventListener('DOMContentLoaded', function () {
                    doc.removeEventListener('DOMContentLoaded', arguments.callee, false);
                    loaded();
                }, false);
                window.addEventListener('load', loaded, false);
            } else if (doc.attachEvent) {
                doc.attachEvent('onreadystatechange', function () {
                    if (doc.readyState === 'complete') {
                        doc.detachEvent('onreadystatechange', arguments.callee);
                        loaded();
                    }
                });
                window.attachEvent('onload', loaded);
                var toplevel = false;
                try {
                    toplevel = window.frameElement === null;
                } catch (e) {
                }
                if (docElem.doScroll && toplevel) {
                    doScrollCheck();
                }
            }
        }
    })();
})(window, undefined);